#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
操作录制器 - 主程序
一个用于录制和重复执行鼠标键盘操作的Windows应用程序

作者: AI Assistant
版本: 1.0.0
"""

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import threading
import json
import os
from datetime import datetime
from pynput import keyboard
import pystray
from PIL import Image, ImageDraw
import io
import base64

from recorder import OperationRecorder
from player import OperationPlayer
from config import Config
from hotkey_settings import HotkeySettingsWindow
from floating_window import FloatingWindow

# 主题配色
COLORS = {
    'bg_primary': '#0a0a0a',      # 玄青黑
    'bg_secondary': '#1a1a1a',    # 深灰
    'bg_tertiary': '#2a2a2a',     # 中灰
    'accent_gold': '#FFD700',     # 鎏金
    'accent_red': '#E53A3A',      # 血月红
    'text_primary': '#FFFFFF',    # 主文字
    'text_secondary': '#CCCCCC',  # 次要文字
    'text_muted': '#888888',      # 暗淡文字
    'success': '#4CAF50',         # 成功绿
    'warning': '#FF9800',         # 警告橙
    'error': '#F44336'            # 错误红
}


class OperationRecorderApp:
    """操作录制器主应用程序类"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("🎯 操作录制器 v1.0")
        self.root.geometry("700x750")
        self.root.resizable(True, True)
        
        # 设置窗口图标
        try:
            icon_path = os.path.join(os.path.dirname(__file__), "icon_control_hover.png")
            if os.path.exists(icon_path):
                # 使用PhotoImage加载PNG图标
                icon_image = tk.PhotoImage(file=icon_path)
                self.root.iconphoto(True, icon_image)
                # 保存引用防止被垃圾回收
                self.icon_image = icon_image
        except Exception as e:
            print(f"加载窗口图标失败: {e}")
        
        # 设置深色主题
        self.root.configure(bg=COLORS['bg_primary'])
        self.setup_styles()
        
        # 初始化组件
        self.recorder = OperationRecorder()
        self.player = OperationPlayer()
        self.config = Config()
        
        # 状态变量
        self.is_recording = False
        self.is_playing = False
        self.current_script = None
        self.script_list = []
        
        # 快捷键监听器
        self.hotkey_listener = None
        self.setup_hotkeys()
        
        # 系统托盘
        self.tray_icon = None
        self.is_hidden = False
        
        # 悬浮窗
        self.floating_window = FloatingWindow(self)
        
        # 创建UI
        self.create_widgets()
        self.load_scripts()
        
        # 绑定事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        
        # 创建系统托盘
        self.create_tray_icon()
    
    def setup_styles(self):
        """设置ttk样式主题"""
        style = ttk.Style()
        
        # 配置主题样式
        style.theme_use('clam')
        
        # 配置Frame样式
        style.configure('Dark.TFrame', 
                       background=COLORS['bg_primary'],
                       borderwidth=0)
        
        # 配置LabelFrame样式
        style.configure('Dark.TLabelframe', 
                       background=COLORS['bg_primary'],
                       bordercolor=COLORS['accent_gold'],
                       borderwidth=2,
                       relief='solid')
        style.configure('Dark.TLabelframe.Label',
                       background=COLORS['bg_primary'],
                       foreground=COLORS['accent_gold'],
                       font=('Microsoft YaHei UI', 10, 'bold'))
        
        # 配置Button样式
        style.configure('Gold.TButton',
                       background=COLORS['accent_gold'],
                       foreground=COLORS['bg_primary'],
                       borderwidth=0,
                       focuscolor='none',
                       font=('Microsoft YaHei UI', 9, 'bold'))
        style.map('Gold.TButton',
                 background=[('active', '#FFE55C'),
                           ('pressed', '#E6C200')])
        
        style.configure('Red.TButton',
                       background=COLORS['accent_red'],
                       foreground=COLORS['text_primary'],
                       borderwidth=0,
                       focuscolor='none',
                       font=('Microsoft YaHei UI', 9, 'bold'))
        style.map('Red.TButton',
                 background=[('active', '#FF6B6B'),
                           ('pressed', '#D32F2F')])
        
        style.configure('Dark.TButton',
                       background=COLORS['bg_tertiary'],
                       foreground=COLORS['text_primary'],
                       borderwidth=1,
                       bordercolor=COLORS['accent_gold'],
                       focuscolor='none',
                       font=('Microsoft YaHei UI', 9))
        style.map('Dark.TButton',
                 background=[('active', COLORS['bg_secondary']),
                           ('pressed', COLORS['bg_primary'])])
        
        # 配置Label样式
        style.configure('Title.TLabel',
                       background=COLORS['bg_primary'],
                       foreground=COLORS['accent_gold'],
                       font=('Microsoft YaHei UI', 12, 'bold'))
        
        style.configure('Status.TLabel',
                       background=COLORS['bg_primary'],
                       foreground=COLORS['text_secondary'],
                       font=('Microsoft YaHei UI', 9))
        
        style.configure('Tip.TLabel',
                       background=COLORS['bg_primary'],
                       foreground=COLORS['text_muted'],
                       font=('Microsoft YaHei UI', 8))
        
        # 配置Entry样式
        style.configure('Dark.TEntry',
                       fieldbackground=COLORS['bg_tertiary'],
                       foreground=COLORS['text_primary'],
                       bordercolor=COLORS['accent_gold'],
                       insertcolor=COLORS['accent_gold'],
                       font=('Microsoft YaHei UI', 9))
        
        # 配置Treeview样式
        style.configure('Dark.Treeview',
                       background=COLORS['bg_secondary'],
                       foreground=COLORS['text_primary'],
                       fieldbackground=COLORS['bg_secondary'],
                       bordercolor=COLORS['accent_gold'],
                       borderwidth=1,
                       font=('Microsoft YaHei UI', 9))
        style.configure('Dark.Treeview.Heading',
                       background=COLORS['bg_tertiary'],
                       foreground=COLORS['accent_gold'],
                       bordercolor=COLORS['accent_gold'],
                       font=('Microsoft YaHei UI', 9, 'bold'))
        style.map('Dark.Treeview',
                 background=[('selected', COLORS['accent_gold'])],
                 foreground=[('selected', COLORS['bg_primary'])])
        
        # 配置Scrollbar样式
        style.configure('Dark.Vertical.TScrollbar',
                       background=COLORS['bg_tertiary'],
                       troughcolor=COLORS['bg_secondary'],
                       bordercolor=COLORS['accent_gold'],
                       arrowcolor=COLORS['accent_gold'],
                       darkcolor=COLORS['bg_tertiary'],
                       lightcolor=COLORS['bg_tertiary'])
    
    def create_widgets(self):
        """创建UI组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="15", style='Dark.TFrame')
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(2, weight=1)
        
        # 标题区域
        title_frame = ttk.Frame(main_frame, style='Dark.TFrame')
        title_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 15))
        
        title_label = ttk.Label(title_frame, text="🎯 操作录制器", style='Title.TLabel')
        title_label.pack(side=tk.LEFT)
        
        version_label = ttk.Label(title_frame, text="v1.0", style='Tip.TLabel')
        version_label.pack(side=tk.RIGHT)
        
        # 录制控制区域
        record_frame = ttk.LabelFrame(main_frame, text="🔴 录制控制", padding="15", style='Dark.TLabelframe')
        record_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 15))
        
        # 录制按钮
        self.record_btn = ttk.Button(record_frame, text="🎬 开始录制", command=self.toggle_recording, style='Gold.TButton')
        self.record_btn.grid(row=0, column=0, padx=(0, 15), pady=(0, 10))
        
        # 录制状态标签
        self.record_status = ttk.Label(record_frame, text="⚪ 未录制", style='Status.TLabel')
        self.record_status.grid(row=0, column=1, padx=(0, 15), pady=(0, 10))
        
        # 保存按钮
        self.save_btn = ttk.Button(record_frame, text="💾 保存录制", command=self.save_recording, state="disabled", style='Dark.TButton')
        self.save_btn.grid(row=0, column=2, pady=(0, 10))
        
        # 快捷键提示
        hotkey_tip = ttk.Label(record_frame, text="⌨️ 快捷键: F9-开始录制 | F10-停止录制 | F11-播放 | F12-停止播放 | Esc-紧急停止", 
                              style='Tip.TLabel')
        hotkey_tip.grid(row=1, column=0, columnspan=3, pady=(10, 0))
        
        # 播放控制区域
        play_frame = ttk.LabelFrame(main_frame, text="▶️ 播放控制", padding="15", style='Dark.TLabelframe')
        play_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 15))
        
        # 播放按钮
        self.play_btn = ttk.Button(play_frame, text="▶️ 播放脚本", command=self.play_script, state="disabled", style='Gold.TButton')
        self.play_btn.grid(row=0, column=0, padx=(0, 15), pady=(0, 10))
        
        # 停止按钮
        self.stop_btn = ttk.Button(play_frame, text="⏹️ 停止播放", command=self.stop_playing, state="disabled", style='Red.TButton')
        self.stop_btn.grid(row=0, column=1, padx=(0, 15), pady=(0, 10))
        
        # 循环次数
        ttk.Label(play_frame, text="🔄 循环次数:", style='Status.TLabel').grid(row=0, column=2, padx=(15, 10), pady=(0, 10))
        self.loop_var = tk.StringVar(value="1")
        loop_entry = ttk.Entry(play_frame, textvariable=self.loop_var, width=8, style='Dark.TEntry')
        loop_entry.grid(row=0, column=3, padx=(0, 15), pady=(0, 10))
        
        # 播放状态
        self.play_status = ttk.Label(play_frame, text="⚪ 未播放", style='Status.TLabel')
        self.play_status.grid(row=0, column=4, pady=(0, 10))
        
        # 脚本管理区域
        script_frame = ttk.LabelFrame(main_frame, text="📁 脚本管理", padding="15", style='Dark.TLabelframe')
        script_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        script_frame.columnconfigure(0, weight=1)
        script_frame.rowconfigure(0, weight=1)
        
        # 脚本列表
        list_frame = ttk.Frame(script_frame, style='Dark.TFrame')
        list_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15))
        list_frame.columnconfigure(0, weight=1)
        list_frame.rowconfigure(0, weight=1)
        
        # 创建Treeview
        columns = ('name', 'date', 'operations')
        self.script_tree = ttk.Treeview(list_frame, columns=columns, show='headings', height=12, style='Dark.Treeview')
        
        # 定义列标题
        self.script_tree.heading('name', text='📝 脚本名称')
        self.script_tree.heading('date', text='📅 创建日期')
        self.script_tree.heading('operations', text='🔢 操作数量')
        
        # 设置列宽
        self.script_tree.column('name', width=250)
        self.script_tree.column('date', width=180)
        self.script_tree.column('operations', width=120)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.script_tree.yview, style='Dark.Vertical.TScrollbar')
        self.script_tree.configure(yscrollcommand=scrollbar.set)
        
        self.script_tree.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
        
        # 绑定选择事件
        self.script_tree.bind('<<TreeviewSelect>>', self.on_script_select)
        self.script_tree.bind('<Double-1>', self.on_script_double_click)
        
        # 按钮区域
        btn_frame = ttk.Frame(script_frame, style='Dark.TFrame')
        btn_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(15, 0))
        
        # 第一行按钮
        ttk.Button(btn_frame, text="🔄 刷新列表", command=self.load_scripts, style='Dark.TButton').grid(row=0, column=0, padx=(0, 10), pady=(0, 8))
        ttk.Button(btn_frame, text="📥 导入脚本", command=self.import_script, style='Dark.TButton').grid(row=0, column=1, padx=(0, 10), pady=(0, 8))
        ttk.Button(btn_frame, text="📤 导出脚本", command=self.export_script, style='Dark.TButton').grid(row=0, column=2, padx=(0, 10), pady=(0, 8))
        
        # 第二行按钮
        ttk.Button(btn_frame, text="🗑️ 删除脚本", command=self.delete_script, style='Red.TButton').grid(row=1, column=0, padx=(0, 10), pady=(0, 8))
        ttk.Button(btn_frame, text="✏️ 重命名", command=self.rename_script, style='Dark.TButton').grid(row=1, column=1, padx=(0, 10), pady=(0, 8))
        ttk.Button(btn_frame, text="📌 最小化到托盘", command=self.hide_window, style='Dark.TButton').grid(row=1, column=2, padx=(0, 10), pady=(0, 8))
        
        # 第三行按钮
        ttk.Button(btn_frame, text="🎯 显示悬浮窗", command=self.toggle_floating_window, style='Gold.TButton').grid(row=2, column=0, padx=(0, 10))
        ttk.Button(btn_frame, text="⭐ 设为默认", command=self.set_default_script, style='Gold.TButton').grid(row=2, column=1, padx=(0, 10))
        ttk.Button(btn_frame, text="⚙️ 快捷键设置", command=self.open_hotkey_settings, style='Gold.TButton').grid(row=2, column=2, padx=(0, 10))
    
    def toggle_recording(self):
        """切换录制状态"""
        if not self.is_recording:
            self.start_recording()
        else:
            self.stop_recording()
    
    def start_recording(self):
        """开始录制"""
        self.is_recording = True
        self.record_btn.config(text="⏹️ 停止录制", style='Red.TButton')
        self.record_status.config(text="🔴 正在录制...")
        self.save_btn.config(state="disabled")
        
        # 更新悬浮窗状态
        self.update_floating_window_states()
        
        # 在新线程中开始录制
        self.recording_thread = threading.Thread(target=self.recorder.start_recording)
        self.recording_thread.daemon = True
        self.recording_thread.start()
    
    def stop_recording(self):
        """停止录制"""
        self.is_recording = False
        self.recorder.stop_recording()
        
        self.record_btn.config(text="🎬 开始录制", style='Gold.TButton')
        self.record_status.config(text="✅ 录制完成")
        self.save_btn.config(state="normal")
        
        # 更新悬浮窗状态
        self.update_floating_window_states()
    
    def save_recording(self):
        """保存录制的操作"""
        if not self.recorder.operations:
            messagebox.showwarning("警告", "没有录制到任何操作！")
            return
        
        # 获取脚本名称
        name = tk.simpledialog.askstring("保存脚本", "请输入脚本名称:")
        if not name:
            return
        
        # 保存脚本
        script_data = {
            'name': name,
            'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'operations': self.recorder.operations.copy()
        }
        
        # 保存到文件
        scripts_dir = "scripts"
        if not os.path.exists(scripts_dir):
            os.makedirs(scripts_dir)
        
        filename = f"{scripts_dir}/{name}.json"
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(script_data, f, ensure_ascii=False, indent=2)
        
        self.load_scripts()
        self.save_btn.config(state="disabled")
        self.record_status.config(text="💾 已保存")
        
        messagebox.showinfo("✅ 成功", f"脚本 '{name}' 已保存！")
    
    def load_scripts(self):
        """加载脚本列表"""
        # 清空现有列表
        for item in self.script_tree.get_children():
            self.script_tree.delete(item)
        
        self.script_list.clear()
        
        scripts_dir = "scripts"
        if not os.path.exists(scripts_dir):
            print("scripts目录不存在")
            return
        
        # 加载所有脚本文件
        script_count = 0
        for filename in os.listdir(scripts_dir):
            if filename.endswith('.json'):
                try:
                    filepath = os.path.join(scripts_dir, filename)
                    with open(filepath, 'r', encoding='utf-8') as f:
                        script_data = json.load(f)
                    
                    # 确保脚本数据包含必要字段
                    if 'name' not in script_data:
                        script_data['name'] = filename[:-5]  # 去掉.json后缀
                    if 'date' not in script_data:
                        script_data['date'] = '未知日期'
                    if 'operations' not in script_data:
                        script_data['operations'] = []
                    
                    self.script_list.append(script_data)

                    script_count += 1
                    print(f"加载脚本: {script_data['name']}, 操作数: {len(script_data['operations'])}")
                    
                except Exception as e:
                    print(f"加载脚本 {filename} 失败: {e}")
        
        print(f"总共加载了 {script_count} 个脚本")
        
        # 更新树形视图显示
        self.update_script_tree_display()
        
        # 检查默认脚本设置
        self.check_and_load_default_script()
        
        # 如果没有选择默认脚本，重置当前选择
        if not self.current_script:
            self.play_btn.config(state="disabled")
    
    def on_script_select(self, event):
        """脚本选择事件"""
        selection = self.script_tree.selection()
        if selection:
            # 获取选中项的索引
            selected_item = selection[0]
            # 获取该项在树形视图中的索引位置
            all_items = self.script_tree.get_children()
            try:
                item_index = list(all_items).index(selected_item)
                
                # 直接使用索引从script_list获取脚本数据
                if 0 <= item_index < len(self.script_list):
                    self.current_script = self.script_list[item_index]
                    script_name = self.current_script['name']
                    self.play_btn.config(state="normal")
                    print(f"选择了脚本: {script_name}, 操作数量: {len(self.current_script['operations'])}")  # 调试信息
                else:
                    print(f"索引超出范围: {item_index}")  # 调试信息
                    self.current_script = None
                    self.play_btn.config(state="disabled")
            except ValueError:
                print("无法找到选中项的索引")  # 调试信息
                self.current_script = None
                self.play_btn.config(state="disabled")
        else:
            print("没有选择任何脚本")  # 调试信息
            self.current_script = None
            self.play_btn.config(state="disabled")
    
    def on_script_double_click(self, event):
        """脚本双击事件 - 直接播放"""
        selection = self.script_tree.selection()
        if selection and self.current_script:
            print("双击播放脚本")
            self.play_script()
    
    def play_script(self):
        """播放脚本"""
        if not self.current_script:
            messagebox.showwarning("警告", "请先选择一个脚本！")
            return
        
        try:
            loop_count = int(self.loop_var.get())
            if loop_count <= 0:
                raise ValueError()
        except ValueError:
            messagebox.showerror("错误", "循环次数必须是正整数！")
            return
        
        self.is_playing = True
        self.play_btn.config(state="disabled")
        self.stop_btn.config(state="normal")
        self.play_status.config(text="▶️ 正在播放...")
        
        # 更新悬浮窗状态
        self.update_floating_window_states()
        
        # 在新线程中播放
        self.playing_thread = threading.Thread(
            target=self._play_script_thread,
            args=(self.current_script['operations'], loop_count)
        )
        self.playing_thread.daemon = True
        self.playing_thread.start()
    
    def _play_script_thread(self, operations, loop_count):
        """播放脚本的线程函数"""
        try:
            self.player.play_operations(operations, loop_count, 
                                      stop_callback=lambda: not self.is_playing)
            
            # 播放完成后更新UI
            self.root.after(0, self._on_play_finished)
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("错误", f"播放失败: {e}"))
            self.root.after(0, self._on_play_finished)
    
    def _on_play_finished(self):
        """播放完成后的UI更新"""
        self.is_playing = False
        self.play_btn.config(state="normal")
        self.stop_btn.config(state="disabled")
        self.play_status.config(text="✅ 播放完成")
        
        # 更新悬浮窗状态
        self.update_floating_window_states()
    
    def stop_playing(self):
        """停止播放"""
        self.is_playing = False
        self.player.stop_playing()
        self._on_play_finished()
        self.play_status.config(text="⏹️ 已停止")
        
        # 更新悬浮窗状态
        self.update_floating_window_states()
    
    def import_script(self):
        """导入脚本"""
        filename = filedialog.askopenfilename(
            title="选择脚本文件",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if filename:
            try:
                with open(filename, 'r', encoding='utf-8') as f:
                    script_data = json.load(f)
                
                # 验证脚本格式
                if not all(key in script_data for key in ['name', 'date', 'operations']):
                    raise ValueError("脚本格式不正确")
                
                # 保存到scripts目录
                scripts_dir = "scripts"
                if not os.path.exists(scripts_dir):
                    os.makedirs(scripts_dir)
                
                new_filename = f"{scripts_dir}/{script_data['name']}.json"
                with open(new_filename, 'w', encoding='utf-8') as f:
                    json.dump(script_data, f, ensure_ascii=False, indent=2)
                
                self.load_scripts()
                messagebox.showinfo("✅ 成功", "脚本导入成功！")
                
            except Exception as e:
                messagebox.showerror("❌ 错误", f"导入失败: {e}")
    
    def export_script(self):
        """导出脚本"""
        if not self.current_script:
            messagebox.showwarning("⚠️ 警告", "请先选择一个脚本！")
            return
        
        filename = filedialog.asksaveasfilename(
            title="保存脚本",
            defaultextension=".json",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if filename:
            try:
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(self.current_script, f, ensure_ascii=False, indent=2)
                messagebox.showinfo("✅ 成功", "脚本导出成功！")
            except Exception as e:
                messagebox.showerror("❌ 错误", f"导出失败: {e}")
    
    def delete_script(self):
        """删除脚本"""
        if not self.current_script:
            messagebox.showwarning("⚠️ 警告", "请先选择一个脚本！")
            return
        
        if messagebox.askyesno("🗑️ 确认删除", f"确定要删除脚本 '{self.current_script['name']}' 吗？"):
            try:
                filename = f"scripts/{self.current_script['name']}.json"
                if os.path.exists(filename):
                    os.remove(filename)
                
                self.current_script = None
                self.play_btn.config(state="disabled")
                self.load_scripts()
                messagebox.showinfo("✅ 成功", "脚本删除成功！")
                
            except Exception as e:
                messagebox.showerror("❌ 错误", f"删除失败: {e}")
    
    def rename_script(self):
        """重命名脚本"""
        if not self.current_script:
            messagebox.showwarning("⚠️ 警告", "请先选择一个脚本！")
            return
        
        new_name = tk.simpledialog.askstring("✏️ 重命名脚本", "请输入新的脚本名称:", 
                                            initialvalue=self.current_script['name'])
        if new_name and new_name != self.current_script['name']:
            try:
                old_filename = f"scripts/{self.current_script['name']}.json"
                new_filename = f"scripts/{new_name}.json"
                
                # 更新脚本数据
                self.current_script['name'] = new_name
                
                # 保存新文件
                with open(new_filename, 'w', encoding='utf-8') as f:
                    json.dump(self.current_script, f, ensure_ascii=False, indent=2)
                
                # 删除旧文件
                if os.path.exists(old_filename):
                    os.remove(old_filename)
                
                self.load_scripts()
                messagebox.showinfo("✅ 成功", "脚本重命名成功！")
                
            except Exception as e:
                messagebox.showerror("❌ 错误", f"重命名失败: {e}")
    
    def create_tray_icon(self):
        """创建系统托盘图标"""
        try:
            # 创建一个简单的图标
            image = self.create_icon_image()
            
            # 创建托盘菜单
            menu = pystray.Menu(
                pystray.MenuItem("🎯 操作录制器", self.show_window, default=True),
                pystray.MenuItem("🎯 悬浮窗", self.tray_toggle_floating_window),
                pystray.Menu.SEPARATOR,
                pystray.MenuItem("🎬 开始录制", self.tray_start_recording, enabled=lambda item: not self.is_recording),
                pystray.MenuItem("⏹️ 停止录制", self.tray_stop_recording, enabled=lambda item: self.is_recording),
                pystray.Menu.SEPARATOR,
                pystray.MenuItem("▶️ 播放脚本", self.tray_play_script, enabled=lambda item: not self.is_playing and self.current_script is not None),
                pystray.MenuItem("⏹️ 停止播放", self.tray_stop_playing, enabled=lambda item: self.is_playing),
                pystray.Menu.SEPARATOR,
                pystray.MenuItem("⚙️ 快捷键设置", self.tray_open_settings),
                pystray.MenuItem("❌ 退出程序", self.tray_quit)
            )
            
            # 创建托盘图标
            self.tray_icon = pystray.Icon(
                "OperationRecorder",
                image,
                "🎯 操作录制器",
                menu
            )
            
            # 在后台线程中运行托盘图标
            threading.Thread(target=self.tray_icon.run, daemon=True).start()
            
        except Exception as e:
            print(f"创建系统托盘失败: {e}")
    
    def create_icon_image(self):
        """创建托盘图标图像"""
        # 创建一个32x32的图像
        width = 32
        height = 32
        image = Image.new('RGBA', (width, height), (0, 0, 0, 0))
        draw = ImageDraw.Draw(image)
        
        # 绘制一个简单的录制图标
        # 外圆
        draw.ellipse([2, 2, width-2, height-2], fill='#FFD700', outline='#E6C200', width=2)
        # 内圆（录制按钮）
        center = width // 2
        radius = 6
        draw.ellipse([center-radius, center-radius, center+radius, center+radius], fill='#E53A3A')
        
        return image
    
    def hide_window(self):
        """隐藏窗口到系统托盘"""
        self.root.withdraw()
        self.is_hidden = True
    
    def show_window(self, icon=None, item=None):
        """从系统托盘显示窗口"""
        self.root.deiconify()
        self.root.lift()
        self.root.focus_force()
        self.is_hidden = False
    
    def tray_start_recording(self, icon, item):
        """托盘菜单：开始录制"""
        if not self.is_recording:
            self.root.after(0, self.start_recording)
    
    def tray_stop_recording(self, icon, item):
        """托盘菜单：停止录制"""
        if self.is_recording:
            self.root.after(0, self.stop_recording)
    
    def tray_play_script(self, icon, item):
        """托盘菜单：播放脚本"""
        if not self.is_playing and self.current_script:
            self.root.after(0, self.start_playing)
    
    def tray_stop_playing(self, icon, item):
        """托盘菜单：停止播放"""
        if self.is_playing:
            self.root.after(0, self.stop_playing)
    
    def tray_toggle_floating_window(self, icon, item):
        """托盘菜单：切换悬浮窗"""
        self.root.after(0, self.toggle_floating_window)
    
    def tray_open_settings(self, icon, item):
        """托盘菜单：打开设置"""
        self.root.after(0, lambda: self.show_window() or self.open_hotkey_settings())
    
    def tray_quit(self, icon, item):
        """托盘菜单：退出程序"""
        self.root.after(0, self.quit_application)
    
    def quit_application(self):
        """完全退出应用程序"""
        if self.is_recording:
            self.stop_recording()
        if self.is_playing:
            self.stop_playing()
        
        # 停止快捷键监听器
        if self.hotkey_listener:
            self.hotkey_listener.stop()
        
        # 销毁悬浮窗
        if self.floating_window:
            self.floating_window.destroy_floating_window()
        
        # 停止托盘图标
        if self.tray_icon:
            self.tray_icon.stop()
        
        self.root.quit()
        self.root.destroy()
    
    def on_closing(self):
        """程序关闭事件 - 最小化到托盘"""
        self.hide_window()
    
    def setup_hotkeys(self):
        """设置全局快捷键"""
        try:
            # 停止现有监听器
            if self.hotkey_listener:
                self.hotkey_listener.stop()
            
            # 获取快捷键配置
            hotkeys = self.config.get('hotkeys', {})
            
            # 创建快捷键映射
            hotkey_combinations = []
            
            # 开始/停止录制
            start_key = hotkeys.get('start_recording', 'F9')
            stop_key = hotkeys.get('stop_recording', 'F10')
            play_key = hotkeys.get('play_script', 'F11')
            stop_play_key = hotkeys.get('stop_playing', 'F12')
            emergency_key = hotkeys.get('emergency_stop', 'Esc')
            
            # 转换按键名称为pynput格式
            def convert_key(key_name):
                key_map = {
                    'F1': keyboard.Key.f1, 'F2': keyboard.Key.f2, 'F3': keyboard.Key.f3,
                    'F4': keyboard.Key.f4, 'F5': keyboard.Key.f5, 'F6': keyboard.Key.f6,
                    'F7': keyboard.Key.f7, 'F8': keyboard.Key.f8, 'F9': keyboard.Key.f9,
                    'F10': keyboard.Key.f10, 'F11': keyboard.Key.f11, 'F12': keyboard.Key.f12,
                    'Esc': keyboard.Key.esc, 'Space': keyboard.Key.space,
                    'Enter': keyboard.Key.enter, 'Tab': keyboard.Key.tab,
                    'Ctrl': keyboard.Key.ctrl, 'Alt': keyboard.Key.alt,
                    'Shift': keyboard.Key.shift
                }
                return key_map.get(key_name, key_name.lower())
            
            # 创建全局快捷键监听器
            def on_hotkey_press(key):
                try:
                    key_name = None
                    if hasattr(key, 'name'):
                        key_name = key.name
                    elif hasattr(key, 'char') and key.char:
                        key_name = key.char.upper()
                    
                    # 转换特殊按键名称
                    if key == keyboard.Key.f9:
                        key_name = 'F9'
                    elif key == keyboard.Key.f10:
                        key_name = 'F10'
                    elif key == keyboard.Key.f11:
                        key_name = 'F11'
                    elif key == keyboard.Key.f12:
                        key_name = 'F12'
                    elif key == keyboard.Key.esc:
                        key_name = 'Esc'
                    
                    if key_name:
                        # 在主线程中执行UI操作
                        self.root.after(0, self.handle_hotkey, key_name)
                        
                except Exception as e:
                    print(f"快捷键处理错误: {e}")
            
            # 启动监听器
            self.hotkey_listener = keyboard.Listener(on_press=on_hotkey_press)
            self.hotkey_listener.start()
            
            print("全局快捷键已启用")
            print(f"开始录制: {start_key}")
            print(f"停止录制: {stop_key}")
            print(f"播放脚本: {play_key}")
            print(f"停止播放: {stop_play_key}")
            print(f"紧急停止: {emergency_key}")
            
        except Exception as e:
            print(f"设置快捷键失败: {e}")
    
    def handle_hotkey(self, key_name):
        """处理快捷键事件"""
        try:
            hotkeys = self.config.get('hotkeys', {})
            
            if key_name == hotkeys.get('start_recording', 'F9'):
                if not self.is_recording:
                    self.toggle_recording()
                    print(f"快捷键触发: 开始录制")
            
            elif key_name == hotkeys.get('stop_recording', 'F10'):
                if self.is_recording:
                    self.toggle_recording()
                    print(f"快捷键触发: 停止录制")
            
            elif key_name == hotkeys.get('play_script', 'F11'):
                if not self.is_playing and self.current_script:
                    self.play_script()
                    print(f"快捷键触发: 播放脚本")
            
            elif key_name == hotkeys.get('stop_playing', 'F12'):
                if self.is_playing:
                    self.stop_playing()
                    print(f"快捷键触发: 停止播放")
            
            elif key_name == hotkeys.get('emergency_stop', 'Esc'):
                if self.is_recording:
                    self.toggle_recording()
                if self.is_playing:
                    self.stop_playing()
                print(f"快捷键触发: 紧急停止")
                
        except Exception as e:
            print(f"快捷键处理错误: {e}")
    
    def open_hotkey_settings(self):
        """打开快捷键设置窗口"""
        HotkeySettingsWindow(self.root, self.config, self.setup_hotkeys)
    
    def toggle_floating_window(self):
        """切换悬浮窗显示状态"""
        self.floating_window.toggle_floating_window()
        
    def show_floating_window(self):
        """显示悬浮窗"""
        self.floating_window.show_floating_window()
        
    def hide_floating_window(self):
        """隐藏悬浮窗"""
        self.floating_window.hide_floating_window()
        
    def update_floating_window_states(self):
        """更新悬浮窗按钮状态"""
        if self.floating_window and self.floating_window.is_visible:
            self.floating_window.update_button_states()
    
    def set_default_script(self):
        """设置当前选中的脚本为默认脚本"""
        if not self.current_script:
            messagebox.showwarning("警告", "请先选择一个脚本！")
            return
        
        script_name = self.current_script['name']
        
        # 确认设置
        result = messagebox.askyesno(
            "确认设置", 
            f"确定要将脚本 '{script_name}' 设为默认脚本吗？\n\n默认脚本将在程序启动时自动选中。"
        )
        
        if result:
            # 保存到配置
            self.config.set('playback.default_script', script_name)
            self.config.save_config()
            
            # 刷新脚本列表显示
            self.load_scripts()
            
            messagebox.showinfo("成功", f"已将脚本 '{script_name}' 设为默认脚本！")
            print(f"设置默认脚本: {script_name}")
    
    def check_and_load_default_script(self):
        """检查并加载默认脚本"""
        default_script_name = self.config.get('playback.default_script')
        
        if not default_script_name:
            # 如果没有设置默认脚本且有可用脚本，提醒用户设置
            if self.script_list:
                self.show_default_script_reminder()
            return
        
        # 查找默认脚本
        default_script_found = False
        for i, script_data in enumerate(self.script_list):
            if script_data['name'] == default_script_name:
                # 找到默认脚本，自动选择
                self.current_script = script_data
                self.play_btn.config(state="normal")
                
                # 在树形视图中选中该项
                all_items = self.script_tree.get_children()
                if i < len(all_items):
                    self.script_tree.selection_set(all_items[i])
                    self.script_tree.focus(all_items[i])
                
                print(f"自动选择默认脚本: {default_script_name}")
                default_script_found = True
                break
        
        if not default_script_found:
            # 默认脚本不存在，清除配置并提醒
            self.config.set('playback.default_script', None)
            self.config.save_config()
            messagebox.showwarning(
                "默认脚本不存在", 
                f"默认脚本 '{default_script_name}' 不存在，已清除默认设置。\n\n请重新设置默认脚本。"
            )
    
    def show_default_script_reminder(self):
        """显示设置默认脚本的提醒"""
        result = messagebox.askyesno(
            "设置默认脚本", 
            "检测到您还没有设置默认脚本。\n\n设置默认脚本后，程序启动时会自动选中该脚本，方便快速播放。\n\n是否现在设置默认脚本？"
        )
        
        if result:
            messagebox.showinfo(
                "如何设置", 
                "请按以下步骤设置默认脚本：\n\n1. 在脚本列表中选择一个脚本\n2. 点击 '⭐ 设为默认' 按钮\n\n设置完成后，该脚本将在下次启动时自动选中。"
            )
    
    def update_script_tree_display(self):
        """更新脚本树形视图显示"""
        default_script_name = self.config.get('playback.default_script')
        
        for i, script_data in enumerate(self.script_list):
            # 检查是否为默认脚本
            display_name = script_data['name']
            if default_script_name and script_data['name'] == default_script_name:
                display_name = f"⭐ {script_data['name']}"
            
            # 添加到树形视图
            self.script_tree.insert('', 'end', values=(
                display_name,
                script_data['date'],
                len(script_data['operations'])
            ))
    
    def run(self):
        """运行应用程序"""
        self.root.mainloop()


if __name__ == "__main__":
    # 导入对话框模块
    import tkinter.simpledialog
    
    app = OperationRecorderApp()
    app.run()